Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse source to output file map from aspect outputgroup JSON files #49

Merged
merged 6 commits into from
Nov 4, 2022

Conversation

thiagohmcruz
Copy link
Collaborator

@thiagohmcruz thiagohmcruz commented Oct 18, 2022

  • Add ability to parse JSON mappings from output groups generated in XCHammer: Add source_output_file_map_aspect and DataStore symlink logic bazel-ios/xchammer#33
  • Read and change behaviour based on config file under path/to/foo.xcodeproj/xcbuildkit.config
  • Used folder to cache indexing data (BUILD_SERVICE_INDEXING_DATA_DIR config), this allows fast load on Xcode launch
  • Conditionally enables indexing and progress bar from config and remove hard coded hacks
  • Adds a bunch of new [WARNING|INFO|ERROR] logs to help with troubleshooting
  • Read .xcodeproj path from CreateSessionRequest
  • Bug fixes
    • Edge case in buffering logic
    • fileHandle?.closeFile() is deprecated, calling .close() now
    • fileHandle.waitForDataInBackgroundAndNotify() is necessary to read the BEP when installed as a pkg on macOS
  • Introduces: WorkspaceInfo, IndexingService, BazelBuildServiceConfig, BEPService, WorkspaceInfoKeyable (see responsibilities of each in comments in code)

@thiagohmcruz thiagohmcruz marked this pull request as ready for review October 18, 2022 18:54
Copy link
Owner

@jerrymarino jerrymarino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thiagohmcruz nice one!

Flipping indexing on SGTM - added a few suggestions inline.

Examples/BazelBuildService/main.swift Outdated Show resolved Hide resolved
Examples/BazelBuildService/main.swift Outdated Show resolved Hide resolved
Examples/BazelBuildService/main.swift Outdated Show resolved Hide resolved
Copy link
Owner

@jerrymarino jerrymarino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one @thiagohmcruz ! Minor tweak for pulling the config down to the request level. It might be a more nuanced change

Examples/BazelBuildService/main.swift Outdated Show resolved Hide resolved
Examples/BazelBuildService/main.swift Outdated Show resolved Hide resolved
Examples/BazelBuildService/main.swift Outdated Show resolved Hide resolved
Examples/BazelBuildService/main.swift Outdated Show resolved Hide resolved
@thiagohmcruz thiagohmcruz merged commit 4c366af into master Nov 4, 2022
Copy link
Owner

@jerrymarino jerrymarino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thiagohmcruz nice one 👏 👏

// so one config per line. This is intentionally simple at the moment but we can add more validation or a more reliable file format later.
//
// TODO: Codable?
// TODO: Not load from disk all the time but still detect changes in the file and refresh in-memory values?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think what you've got here is good for now and this is a tricky thing to deal with.

</plist>
"""
guard let converter = BPlistConverter(xml: xml) else {
fatalError("Failed to allocate converter")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if you'd also instead tried propagate an empty data blob in this case or does that hang the build service? I imagined they had some form of error handling for a message like this and we could hook that

Minor - we should have a nice formatter on the repo longer term probably 😅

// Create key
let sourceKey = filePath.replacingOccurrences(of: workingDir, with: "").replacingOccurrences(of: (info.config.bazelWorkingDir ?? ""), with: "")
// Loops until found
for (_, json) in info.outputFileForSource {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we can circle back if perf is an issue on this. Is it fair to say the runtime complexity of this O(N) output files for a given project?

From what I looked at in going into outputFileForSource - I was wondering if we could compute the dictionary key / source file and get this in O(1) time

fatalError("[ERROR] Failed to build SDK path, platform is empty.")
}

return "\(info.xcode)/Contents/Developer/Platforms/\(msg.platform).platform/Developer/SDKs/\(msg.sdk).sdk"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wondered if we can get this from the request messages in Xcode 14 - if they have SDKs living outside of Xcode.

// Xcode will try to find the data store under DerivedData so we need to symlink it to `BazelBuildServiceConfig.indexStorePath`
// if that value was set in the config file.
//
// This function manages creating a symlink if it doesn't exist and it creates a backup with the `.default` suffix before doing that. Additionally,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Massive improvement and putting it here - looks overall way cleaner than what it did before

log("[ERROR] Failed to start BEP stream with error: " + error.localizedDescription)
}
} else {
log("[WARNING] BEP string config key 'BUILD_SERVICE_BEP_PATH' empty. Bazel information won't be available during a build.")
}

// This information was not explicitly available in `CreateSessionRequest`, parse from `CreateBuildRequest` instead
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for leaving this comment here - I wonder if that's because it loads the workspaces async.. Seems good like this none the less

@@ -68,6 +68,8 @@ private var workspaceName = ""
// TODO: parsed in `IndexingInfoRequested`, there's probably a less hacky way to get this.
// Effectively `$PWD/iOSApp`
private var workingDir = ""
// Path to derived data for the current workspace
private var derivedDataPath = ""
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the next time we look at it - it help future bistandard to have comment about the global situation of the state problem of these vars!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants